package com.xiaobaibai.security.master_login.config;

import com.xiaobaibai.security.handler.HttpFailureHandler;
import com.xiaobaibai.security.master_login.dao.LoginUserDetailService;
import com.xiaobaibai.security.master_login.filter.MyUsernamePasswordAuthenticationFilter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

//@Configuration
public class LoginConfig <T extends LoginConfig<T, B>, B extends HttpSecurityBuilder<B>>
        extends AbstractHttpConfigurer<T, B> {

    /**
     * AbstractHttpConfigurer 针对Http请求的安全适配器
     * 开始组装
     */

    private MyUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter;

    private LoginUserDetailService userDetailService;

    private PasswordEncoder passwordEncoder;

    private AuthenticationFailureHandler httpFailureHandler;

    public LoginConfig(){
        myUsernamePasswordAuthenticationFilter=new MyUsernamePasswordAuthenticationFilter();
    }

    @Override
    public void configure(B http) throws Exception {
        //设置Filter使用的AuthenticationManager,这里取公共的即可
        myUsernamePasswordAuthenticationFilter
                .setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
        myUsernamePasswordAuthenticationFilter
                .setAuthenticationFailureHandler(new HttpFailureHandler());
        myUsernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(httpFailureHandler);

        //实例filter
        MyUsernamePasswordAuthenticationFilter filter =
                postProcess(this.myUsernamePasswordAuthenticationFilter);

        DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider();
        daoProvider.setUserDetailsService(userDetailService);
        daoProvider.setPasswordEncoder(passwordEncoder);

        http.authenticationProvider(daoProvider)
                .addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
    }

    public LoginConfig<T,B> loginSuccessHandler(AuthenticationSuccessHandler authSuccessHandler){
        myUsernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(authSuccessHandler);
        return this;
    }

    public LoginConfig<T,B> setUserDetailService(LoginUserDetailService userDetailService) {
        this.userDetailService = userDetailService;
        return this;
    }

    public LoginConfig<T,B> setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
        return this;
    }

    public LoginConfig<T,B> setHttpFailureHandler(AuthenticationFailureHandler httpFailureHandler) {
        this.httpFailureHandler = httpFailureHandler;
        return this;
    }
}